package h5

import (
	. "chess_platform/internal/common"
	"chess_platform/models/h5"
	"chess_platform/modules"
	"fmt"
	"github.com/astaxie/beego/orm"
	"strings"
	"time"
)

//[h5]支付,对外接口，不需要token
type PayController struct {
	BaseController
}

func (b *PayController) URLMapping() {
	b.Mapping("IPayCallBack", b.IPayCallBack)
}

// @Title 爱贝支付回调接口(代理与玩家支付都可以回调此接口)
// @Description 爱贝支付回调接口(代理与玩家支付都可以回调此接口)
// @Success 0 {string} 状态码
// @router /ipay-callback [post]
func (b *PayController) IPayCallBack() {
	pay, err := H5IPay.ParseNotifyInfo(b.Ctx.Input.RequestBody)
	if err != nil {
		LogH5.Error(fmt.Sprintf("爱贝回调解析失败:%v\n回调参数(原始的):%v\n,回调参数(解析后):%#v\n",
			err, string(b.Ctx.Input.RequestBody), pay))
		return
	}
	LogH5.Debug(fmt.Sprintf("回调参数(原始的):%v\n,回调参数(解析后):%#v\n", string(b.Ctx.Input.RequestBody), pay))
	//rsp不会为nil
	//获取订单详情
	orderId := strings.Split(pay.CpOrderId, "-")[1]
	order, err := h5.OrderById(orderId)
	if err != nil {
		LogH5.Error(err.Error())
		return
	}
	//订单不存在
	if order == nil {
		return
	}

	//此订单已是成功发货的了，说明是微信重复通知，只需直接返回即可
	if order.Status == OrderDelivered {
		b.ResponseRawString("SUCCESS")
		return
	}

	if pay.Result == 1 { //交易失败,更新数据库订单为失败
		updateData := map[string]interface{}{
			"status":   OrderClosed,
			"pay_time": time.Now().Unix(),
		}
		_, err := h5.UpdateOrder(updateData, orderId)
		if err != nil {
			LogH5.Error(fmt.Sprintf("爱贝回调更新订单失败:%v", err.Error()))
			return
		}

	}
	//支付成功
	updateData := map[string]interface{}{
		"status":   OrderPaySuccess,
		"pay_time": time.Now().Unix(),
	}
	_, err = h5.UpdateOrder(updateData, orderId)
	if err != nil {
		LogH5.Error(err.Error())
		return
	}

	if order.OrderType == OrderDiamond {
		if order.UserType == Player {
			err = dealPlayerIPay(order)
		} else if order.UserType == Agent {
			err = dealAgentIPay(order)
		} else {
			LogH5.Error(fmt.Sprintf("此订单用户类型(ID:%v)错误,用户类型为:%v", order.Id, order.UserType))
			return
		}
		if err != nil {
			LogH5.Error(err.Error())
			return
		}
	} else if order.OrderType == OrderAgentNum {
		//代理加上代理名额
		_, err = h5.UpdateUserAgentNum(order.CardNum, order.Uid)
		if err != nil {
			LogH5.Error(fmt.Sprintf("给代理(ID:%v)加上代理名额(%v)失败:%v", order.Uid, order.CardNum, err))
			return
		}
	}
	LogH5.Debug(fmt.Sprintf("爱贝回调:%v", pay))
	b.ResponseRawString("SUCCESS")
	return
}

func dealAgentIPay(order *Order) error {
	o := orm.NewOrm()
	o.Using(DBChessCenter)
	o.Begin()
	defer o.Rollback()
	//-----------------------------------------------------------------
	/*如果说是第一次充值买卡
	  1.如果说是一级代理,要生成一个授权码
	  2.要在h5_card_cash增加一条记录
	  3.改变用户的状态为正式代理,并且把代理成为正式代理的时间(agent_time)设为当前
	*/
	//首先判断是否为第一次充值买卡,要把开通费用记录到h5_card_cash表里
	if order.IsFirst == FirstTimeBuyCard {
		err := modules.InitAgent(order.Uid, order.Amount)
		if err != nil {
			//初始化失败
			LogH5.Error(err.Error())
			return err
		}
	}

	//给代理发货
	err := modules.DeliveryH5AgentCard(order.Uid, order.CardNum, order.GiveNum,
		order.Amount, order.Id, o)
	if err != nil {
		o.Rollback()
		eventLog := map[string]interface{}{
			"module":     ModuleCard,
			"event_type": EventDelivery,
			"user_type":  Agent,
			"uid":        order.Uid,
			"msg":        fmt.Sprintf("订单:%v发货失败,请联系开发人员", order.Id),
		}
		go NewEventLog(eventLog)
		LogH5.Error(err.Error())
		return err
	}
	//发放提成
	err = modules.BonusAgent(order, o)
	if err != nil {
		o.Rollback()
		eventLog := map[string]interface{}{
			"module":     ModuleCard,
			"event_type": EventDelivery,
			"user_type":  Agent,
			"uid":        order.Uid,
			"msg":        fmt.Sprintf("订单:%v发放提成给代理失败,请联系开发人员", order.Id),
		}
		go NewEventLog(eventLog)
		LogH5.Error(err.Error())
		return err
	}

	return o.Commit()
}

func dealPlayerIPay(order *Order) error {
	o := orm.NewOrm()
	o.Using(DBChessCenter)
	o.Begin()
	defer o.Rollback()

	/*首先判断是否为玩家直充,如果是
	1.要与游戏服通信，通信成功表示游戏服给用户加上了钻石
	2.要给相应的代理提成
	3.要写提成记录
	*/
	//玩家直充
	//发货给玩家
	err := modules.DeliveryH5PlayerCard(order.Uid, order.AgentId, order.CardNum, order.GiveNum, order.Amount, order.Id, o)
	if err != nil {
		o.Rollback()
		LogH5.Error(err.Error())
		return err
	}
	//发放提成
	err = modules.BonusPlayer(order, o)
	if err != nil {
		o.Rollback()
		eventLog := map[string]interface{}{
			"module":     ModuleCard,
			"event_type": EventDelivery,
			"user_type":  Player,
			"uid":        order.Uid,
			"msg":        fmt.Sprintf("订单:%v发放提成给代理失败,请联系开发人员", order.Id),
		}
		go NewEventLog(eventLog)
		LogH5.Error(err.Error())
		return err
	}
	return o.Commit()
}
